/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include "intern/绘图框架.h"
//#include "core/Mesh.h"
#include "core/设备内存缓存.h"




S_绘图框架* f_创建绘图框架(E_绘图API apiName);

//S_设备环境	f_创建协处理器设备(uint32 物理设备, E_设备类型 类型, E_绘图API apiName = E_绘图API::E_Vulkan);


void* f_draw_创建绘图设备(S_设备环境& dev);
void  f_draw_销毁绘图设备(void* 绘图设备);

Inline S_绘图设备* f_df_get绘图环境(S_设备环境& ctx) { return (S_绘图设备*)(ctx.m_绘图设备配置); }


E_绘图API	f_get后端框架名称();

void*		f_get设备();
void*		f_get命令列表();
void*		f_get环境();


S_板载缓存*	f_创建GUP常量缓存(E_板载缓存类型 type, uint64 size);



//S_着色* f_create着色(S_设备环境& ctx, std::vector<S_着色器加载参数> paths);
S_着色* f_create着色(S_设备环境& ctx, S_线管创建配置 ini);
S_线管* f_create线管(S_设备环境& ctx, S_着色& shader, const S_线管创建参数& 线管参数, std::string name = "");
S_线管* f_Gpu_create计算线管(S_设备环境& ctx, S_着色& shader, std::string name="");

Inline void f_df_创建材质着色器(S_设备环境& ctx, S_材质* material, S_线管创建配置& 图元配置, S_线管创建参数& 线管参数) {
	material->m_Shader = f_create着色(ctx, 图元配置);
	material->m_Pipeline = f_create线管(ctx, *material->m_Shader, 线管参数);
	material->m_Shader->f_alloc参数设置(&(material->m_GPU参数set));
}

S_线管*		f_df_create光追管线(S_设备环境& ctx, const S_线管创建配置& 线管参数);
S_光追后端*	f_df_create光追后端(S_设备环境& ctx, const S_线管创建配置& 线管参数);
void        f_df_销毁光追后端(S_光追后端* 光追后端);
void		f_df_光追后端_重构着色器(S_光追后端* rt);

void		f_bd_安装光追材质着色器(S_光追后端* rt, int32 loc, std::string path, uint32 光追ID);
void		f_bd_删除光追材质着色器(S_光追后端* rt, int32 loc);

bool		f_bd_GLSLtoSPV(E_着色阶段 阶段, const std::string code, const std::string 保存路径);

void		f_df_构建顶层光追加速(S_设备环境& ctx, std::vector<S_GPU内存块索引>& 光追实例加速结构, S_GPU内存块索引& 顶层加速结构);


void	f_push板载缓存(S_着色* shader, void* data, uint64 bitSize);

S_结构对象指针	f_gpu_创建参数布局(S_板载缓存* 渲染参数, uint32 binding, uint32 阶段分布);
void			f_setGPU参数布局(S_板载缓存* 渲染参数, S_结构对象指针 GPU参数set);

//void	f_setGPU参数布局_2D绘制(S_着色* shader, S_2D绘制GPU全局参数& view, S_板载缓存** 参数元素, uint16 num, S_纹理** 纹理参数, uint16 texNum);
void	f_setGPU参数布局_2D绘制(S_着色* shader, S_2D绘制GPU全局参数& view);
void	f_setGPU参数布局(S_着色* shader, S_结构对象指针 dstSet, const S_GPU参数布局& GPU参数);
void	f_setGPU参数布局(S_材质* 材质, const S_GPU参数布局& GPU参数);
void	f_df_setGPU参数槽(S_结构对象指针 device, S_结构对象指针 GPU参数设置, const S_GPU参数槽& GPU参数);
void	f_setGPU参数布局(S_GPU计算* GPU, const S_GPU参数布局& GPU参数);
//void	f_setGPU参数布局(S_材质* 材质, S_结构对象指针 dstSet, S_板载缓存** 参数元素, uint16 num, S_纹理** 纹理参数, uint16 texNum);

void	f_df_upGPU参数(S_结构对象指针 device, S_结构对象指针 GPU参数设置, const S_GPU参数槽& GPU参数);



void f_绑定Vertex(S_设备环境& ctx, S_板载缓存组* bg);
void f_绑定Index(S_设备环境& ctx, S_板载缓存* buf);

void f_Draw_序列(S_设备环境& ctx, S_材质* material, S_板载缓存* bg, S_渲染参数& 渲染参数);
void f_Draw_间接序列(S_设备环境& ctx, S_材质* material, S_板载缓存* 顶点, S_渲染参数& 渲染参数);
void f_Draw_索引三角形(S_设备环境& ctx, S_材质* material, S_板载缓存* vert, S_索引渲染参数& 索引渲染参数, S_渲染参数& 渲染参数);
void f_Draw2D_索引三角形(S_设备环境& ctx, S_材质* material, S_板载缓存* vert, S_索引渲染参数& 索引渲染参数, S_渲染参数& 渲染参数);

void f_GPU_run计算(S_GPU计算* gpu, uvec3 dim, void* data = nullptr, uint32 size = 0, uint8 列队 = 0);
void f_GPU_run计算(S_GPU计算* gpu, S_结构对象指针 命令缓存, uvec3 dim, void* data = nullptr, uint32 size = 0, uint8 列队 = 0);



void f_RayDraw_索引三角形(S_设备环境& ctx, S_材质* material, S_索引渲染参数& 索引渲染参数, S_渲染参数& 渲染参数);





void f_Draw2D点(S_设备环境& ctx, std::vector<S_板载缓存*>& bg, S_渲染参数& 渲染参数, bool 是否填充);
void f_Draw2D线(S_设备环境& ctx, std::vector<S_板载缓存*>& bg, S_渲染参数& 渲染参数, bool 是否闭合);
void f_Draw2D多边形(S_设备环境& ctx, std::vector<S_板载缓存*>& bg, S_渲染参数& 渲染参数);











//S_渲染环境* f_创建渲染环境(S_设备环境& ctx, E_MS次数 采样);


S_帧缓存*	f_创建帧缓存(S_设备环境& ctx, const uvec2& faceSize, S_纹理** colors, uint32 num);

void		f_构建帧多重采样缓存(S_设备环境& ctx, S_帧缓存* frame, const uvec2& faceSize, S_纹理** colors, uint32 num);


S_设备环境* f_创建渲染环境(S_设备环境& ctx, E_纹理格式 cf, E_纹理格式 df, E_MS次数 采样, const vec4& 清屏信息, uint16 线程数 = 1);
S_设备环境* f_创建计算环境(S_设备环境& ctx, uint16 线程数 = 1);

void	f_修改帧缓存大小(S_帧缓存* frame, uvec2 size);


S_子集绘图命令* f_bd_创建子集绘图命令(S_绘图设备* 绘图设备, uint32 线程数量);
void f_Draw_Begin(S_子集绘图命令* 绘图命令, uint8 id);
void f_Draw_end(S_子集绘图命令* 绘图命令, uint8 id);


void f_Draw_Begin_帧缓存(S_设备环境* 绘图配置, S_帧缓存* frame, uint8 id);
void f_Draw_end_帧缓存(S_设备环境* 绘图配置);

//void f_Draw_Begin_帧缓存(S_设备环境* 绘图配置, S_帧缓存* frame, S_结构对象指针 命令缓存, uint8 id);
//void f_Draw_end_帧缓存(S_设备环境* 绘图配置, S_结构对象指针 命令缓存, S_结构对象指针 fenc = nullptr);



void f_Draw_Begin(S_结构对象指针 命令缓存, S_设备环境* 绘图配置, S_帧缓存* frame, uint8 id);
void f_Draw_end(S_结构对象指针 命令缓存, S_设备环境* 绘图配置);

//void f_Draw_Begin(S_结构对象指针 命令缓存, S_设备环境* 绘图配置, S_帧缓存* frame, uint8 id);
//void f_Draw_end(S_结构对象指针 命令缓存, S_设备环境* 绘图配置);

void f_Draw_Begin(S_设备环境* ctx, uint8 id);
void f_Draw_end(S_设备环境* ctx);

void f_Draw_Begin(S_设备环境* ctx, S_结构对象指针 命令缓存, S_结构对象指针 fence);
void f_Draw_end(S_设备环境* ctx, S_结构对象指针 命令缓存, S_结构对象指针 fence, uint8 列队=0);


//void f_surface_构建底层加速结构(S_Mesh* mesh);
void f_Draw_构建底层加速结构(S_设备环境* 绘图配置, uint8 id);
void f_Draw_构建顶层加速结构(S_设备环境* 绘图配置, S_帧缓存* frame, uint8 id);



S_GPU计算* f_gpu_create并行计算实例(S_设备环境& ctx, std::string path, const std::vector<S_着色器创建参数>& 参数配置, const std::vector<S_着色器常量推送创建参数>& 常量 = {});

bool	f_device_是否支持光追(const S_设备& dev);
bool	f_device_是否支持光追(const S_协处理设备& dev);


S_设备 f_get最强计算性能设备(const std::vector<S_设备>& 设备);


